package com.vcc.web.controller;


import cn.dev33.satoken.annotation.SaCheckPermission;
import com.mybatisflex.core.paginate.Page;
import com.vcc.core.annotations.RestPack;
import com.vcc.core.exception.ProgramException;
import com.vcc.core.util.RedisCustomizeUtils;
import com.vcc.data.entity.ClientPermission;
import com.vcc.data.entity.ClientRolePermission;
import com.vcc.data.entity.Role;
import com.vcc.data.entity.User;
import com.vcc.service.client.dto.role.CreateRoleDto;
import com.vcc.service.client.dto.role.UpdateRoleDto;
import com.vcc.service.client.vo.role.ClientPermissionVo;
import com.vcc.service.client.vo.role.RoleVo;
import com.vcc.service.service.*;
import com.vcc.web.core.util.UserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@RestController
@RequestMapping("role")
public class RoleController {

    @Autowired
    private RoleService roleService;

    @Autowired
    private UserService userService;

    @Autowired
    private ClientPermissionService clientPermissionService;

    @Autowired
    private ClientRolePermissionService clientRolePermissionService;
    @Autowired
    private UserRoleService userRoleService;

    @RestPack
    @GetMapping("listAll")
    @SaCheckPermission("user:role:view")
    public List<RoleVo> listAll(String code, String name) {
        User user = UserUtil.get();
        Long loginParent = user.getParentId();
        Role loginRole = UserUtil.getRole();
        return roleService.listByUserId(
                loginRole,
                loginRole.getHasAllData() && loginParent != null && loginParent != 0 ? loginParent : user.getId(),
                code,
                name
        ).stream().map(role -> {
            List<ClientPermission> clientPermissions = clientPermissionService.listByRoleId(role.getId());
            ArrayList<ClientPermissionVo> clientPermissionVos = new ArrayList<>();
            List<ClientPermission> parentId = clientPermissions.stream().filter(ClientPermission::getHasParent).toList();
            for (ClientPermission clientPermission : parentId) {
                ClientPermissionVo clientPermissionVo = new ClientPermissionVo(clientPermission);
                List<ClientPermissionVo> children = clientPermissions
                        .stream()
                        .filter(it -> it.getParentId().equals(clientPermission.getId()))
                        .toList()
                        .stream()
                        .map(ClientPermissionVo::new)
                        .toList();
                clientPermissionVo.setChildren(children);
                clientPermissionVos.add(clientPermissionVo);
            }
            role.setPermissionVos(clientPermissionVos);
            return role;
        }).toList();
    }


    @RestPack
    @GetMapping("paging")
    @SaCheckPermission("user:role:view")
    public Page<RoleVo> paging(Integer pageNumber, Integer pageSize, String code, String name) {
        User user = UserUtil.get();
        Long parentId = user.getParentId();
        Role loginRole = UserUtil.getRole();
        Page<RoleVo> page = roleService.paging(
                pageNumber,
                pageSize,
                loginRole,
                loginRole.getHasAllData() && parentId != null && parentId != 0 ? parentId : user.getId(),
                code,
                name
        );
        return page.map(role -> {
            List<ClientPermission> clientPermissions = clientPermissionService.listByRoleId(role.getId());
            ArrayList<ClientPermissionVo> clientPermissionVos = new ArrayList<>();
            List<ClientPermission> parentClientPermissions = clientPermissions.stream().filter(ClientPermission::getHasParent).toList();
            for (ClientPermission clientPermission : parentClientPermissions) {
                ClientPermissionVo clientPermissionVo = new ClientPermissionVo(clientPermission);
                List<ClientPermissionVo> children = clientPermissions
                        .stream()
                        .filter(it -> it.getParentId().equals(clientPermission.getId()))
                        .toList()
                        .stream()
                        .map(ClientPermissionVo::new)
                        .toList();
                clientPermissionVo.setChildren(children);
                clientPermissionVos.add(clientPermissionVo);
            }
            role.setPermissionVos(clientPermissionVos);
            return role;
        });
    }


//    @RestPack
//    @ROReject
//    @KycReject
//    @SaCheckPermission("role:user:edit")
//    @PostMapping("updateUserRole")
//    public Boolean updateUserRole(
//            @RequestBody UpdateUserRoleDto updateUserRoleDto
//    ) {
//        Long userId = UserUtil.getId();
//        if (userId.equals(updateUserRoleDto.getUserId())) {
//            throw new ProgramException("不能自己调整自己的权限");
//        }
//        User user = userService.getById(updateUserRoleDto.getUserId());
//        if (!user.getBeLongToDealer().equals(userId)) {
//            throw new ProgramException("当前帐号不归属与您。无法修改");
//        }
//        if (!roleService.existsById(updateUserRoleDto.getId())) {
//            throw new ProgramException("权限不存在");
//        }
//        Role sourceRole = roleService.getRole(updateUserRoleDto.getUserId());
//        if (sourceRole.getId().equals(updateUserRoleDto.getId())) {
//            throw new ProgramException("权限前后调整一致无需修改");
//        }
//        return roleService.updateUserRole(updateUserRoleDto.getUserId(), updateUserRoleDto.getId(), sourceRole.getId());
//    }


    @RestPack
    @PostMapping("createRole")
    @SaCheckPermission("user:role:create")
    public Boolean createRole(@RequestBody CreateRoleDto createRoleDto) {
        Long userId = UserUtil.getId();
        if (roleService.existsByUserIdAndCode(userId, createRoleDto.getCode())) {
            throw new ProgramException("角色代码已经存在");
        }
        if (createRoleDto.getPermissions().isEmpty()) {
            throw new ProgramException("权限必须选择");
        }
        List<ClientPermission> clientPermissions = clientPermissionService.listByIds(createRoleDto.getPermissions());
        Role role = new Role();
        role.setUserId(userId);
        role.setName(createRoleDto.getName());
        role.setCode(createRoleDto.getCode());
        role.setHasAllData(createRoleDto.getHasAllData());
        role.setHasClientUpdate(true);
        role.setHasClientIntoRole(false);
        role.setStatus(0);
        roleService.save(role);
        Set<Long> tempList = new HashSet<>();
        for (ClientPermission clientPermission : clientPermissions) {
            if (clientPermission.getHasParent()) {
                tempList.addAll(clientPermissionService.listIdsByParentId(clientPermission.getId()));
            } else {
                tempList.add(clientPermission.getId());
                tempList.add(clientPermission.getParentId());
            }
        }
        List<ClientRolePermission> clientRolePermissions = tempList.stream().map(it -> {
            ClientRolePermission clientRolePermission = new ClientRolePermission();
            clientRolePermission.setRoleId(role.getId());
            clientRolePermission.setPermissionId(it);
            return clientRolePermission;
        }).toList();
        clientRolePermissionService.saveBatch(clientRolePermissions);
        return true;
    }

    @RestPack
    @PostMapping("updateRole")
    @SaCheckPermission("user:role:edit")
    public Boolean updateRole(@RequestBody UpdateRoleDto updateRoleDto) {
        Long userId = UserUtil.getId();
        Role role = roleService.getById(updateRoleDto.getId());
        if (!role.getHasClientUpdate()) {
            throw new ProgramException("当前角色不允许修改");
        }
        if (updateRoleDto.getPermissions().isEmpty()) {
            throw new ProgramException("权限必须选择");
        }
        List<ClientPermission> clientPermissions = clientPermissionService.listByIds(updateRoleDto.getPermissions());
        Set<Long> tempList = new HashSet<>();
        for (ClientPermission clientPermission : clientPermissions) {
            if (clientPermission.getHasClientChecked() == null || !clientPermission.getHasClientChecked()) {
                throw new ProgramException("当前存在无法选择的权限,请稍后联系管理员");
            }
            if (clientPermission.getHasParent()) {
                tempList.addAll(clientPermissionService.listIdsByParentId(clientPermission.getId()));
            } else {
                tempList.add(clientPermission.getId());
                tempList.add(clientPermission.getParentId());
            }
        }
        roleService.updateNameAndHasAllDataById(
                role.getId(),
                updateRoleDto.getName(),
                updateRoleDto.getHasAllData()
        );
        clientRolePermissionService.deleteByRoleId(role.getId());
        List<ClientRolePermission> clientRolePermissions = tempList.stream().map(it -> {
            ClientRolePermission clientRolePermission = new ClientRolePermission();
            clientRolePermission.setRoleId(role.getId());
            clientRolePermission.setPermissionId(it);
            return clientRolePermission;
        }).toList();
        clientRolePermissionService.saveBatch(clientRolePermissions);
        List<String> keys = userRoleService.listUserIdByRoleId(role.getId()).stream().map(it -> "user_client_permission:" + it).toList();
        if (!keys.isEmpty()) {
            RedisCustomizeUtils.removeKeys(keys);
        }
        return true;
    }


}
